src/pages/posts/[...page].astro 2.9 K raw
1
---
2
import type { Page, GetStaticPathsOptions } from "astro";
3
import type { CollectionEntry } from "astro:content";
4
import { getCollection } from "astro:content";
5
import PageLayout from "@/layouts/Base";
6
import PostPreview from "@/components/blog/PostPreview";
7
import Pagination from "@/components/Paginator";
8
import { getUniqueTags, sortMDByDate } from "@/utils";
9
10
export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
11
	const allPosts = await getCollection("post");
12
	const allPostsByDate = sortMDByDate(allPosts);
13
	const uniqueTags = getUniqueTags(allPosts);
14
	return paginate(allPostsByDate, { props: { uniqueTags }, pageSize: 10 });
15
}
16
17
interface Props {
18
	page: Page<CollectionEntry<"post">>;
19
	uniqueTags: string[];
20
}
21
22
const { page, uniqueTags } = Astro.props;
23
24
const meta = {
25
	title: "Posts",
26
	description: "A collection of posts by me for an Asto starter theme",
27
};
28
29
const paginationProps = {
30
	...(page.url.prev && {
31
		prevUrl: {
32
			url: page.url.prev,
33
			text: `← Previous Posts`,
34
		},
35
	}),
36
	...(page.url.next && {
37
		nextUrl: {
38
			url: page.url.next,
39
			text: `Next Posts →`,
40
		},
41
	}),
42
};
43
---
44
45
<PageLayout meta={meta}>
46
	<h1 class="title mb-6">Posts</h1>
47
	<div class="grid gap-y-16 sm:grid-cols-[3fr_1fr] sm:gap-x-8">
48
		<section aria-label="Blog post list">
49
			<ul class="space-y-8 text-left">
50
				{
51
					page.data.map((p) => (
52
						<li class="flex flex-col flex-wrap gap-x-2 sm:flex-row [&_q]:w-full">
53
							<PostPreview post={p} as="h2" withDesc />
54
						</li>
55
					))
56
				}
57
			</ul>
58
			<Pagination {...paginationProps} />
59
		</section>
60
		{
61
			uniqueTags.length && (
62
				<aside>
63
					<h2 class="mb-4 flex items-center text-lg font-semibold">
64
						<svg
65
							aria-hidden="true"
66
							xmlns="http://www.w3.org/2000/svg"
67
							class="h-6 w-6"
68
							viewBox="0 0 24 24"
69
							stroke-width="1.5"
70
							stroke="currentColor"
71
							fill="none"
72
							stroke-linecap="round"
73
							stroke-linejoin="round"
74
						>
75
							<path stroke="none" d="M0 0h24v24H0z" fill="none" />
76
							<path d="M7.859 6h-2.834a2.025 2.025 0 0 0 -2.025 2.025v2.834c0 .537 .213 1.052 .593 1.432l6.116 6.116a2.025 2.025 0 0 0 2.864 0l2.834 -2.834a2.025 2.025 0 0 0 0 -2.864l-6.117 -6.116a2.025 2.025 0 0 0 -1.431 -.593z" />
77
							<path d="M17.573 18.407l2.834 -2.834a2.025 2.025 0 0 0 0 -2.864l-7.117 -7.116" />
78
							<path d="M6 9h-.01" />
79
						</svg>
80
						Tags
81
					</h2>
82
					<ul class="flex flex-wrap gap-2 text-bgColor">
83
						{uniqueTags.map((tag) => (
84
							<li>
85
								<a
86
									class="flex items-center justify-center rounded-lg bg-accent p-1"
87
									href={`/tags/${tag}`}
88
									aria-label={`View all posts with the tag: ${tag}`}
89
								>
90
									{tag}
91
								</a>
92
							</li>
93
						))}
94
					</ul>
95
					<span class="mt-4 block sm:text-right">
96
						<a class="sm:hover:text-accent" href="/tags" aria-label="View all blog categories">
97
							View all →
98
						</a>
99
					</span>
100
				</aside>
101
			)
102
		}
103
	</div>
104
</PageLayout>